// 给定一个整数数组 A，我们只能用以下方法修改该数组：我们选择某个个索引 i 并将 A[i] 替换为 -A[i]，然后总共重复这个过程 K 次。（我们可以多次选择同一个索引 i。）

// 以这种方式修改数组后，返回数组可能的最大和。

//  

// 示例 1：

// 输入：A = [4,2,3], K = 1
// 输出：5
// 解释：选择索引 (1,) ，然后 A 变为 [4,-2,3]。
// 示例 2：

// 输入：A = [3,-1,0,2], K = 3
// 输出：6
// 解释：选择索引 (1, 2, 2) ，然后 A 变为 [3,1,0,2]。
// 示例 3：

// 输入：A = [2,-3,-1,5,-4], K = 2
// 输出：13
// 解释：选择索引 (1, 4) ，然后 A 变为 [2,3,-1,5,4]。
//  

// 提示：

// 1 <= A.length <= 10000
// 1 <= K <= 10000
// -100 <= A[i] <= 100

#include "../stdc++.h"

class Solution {
public:
    int largestSumAfterKNegations(vector<int>& A, int K) {
        sort(A.begin(), A.end()); // 从小到大排序
        int n = A.size();
        for (int i{0}; i < n; ++i) {
            if (K > 0 && A[i] < 0) {
                A[i] *= -1;
                --K;
            } else if (K > 0 && A[i] >= 0) {
                if (K % 2 == 0) return sum(A);
                else {
                    int a{0};
                    if (i == 0) a = A[i];
                    else a = A[i] > A[i-1] ? A[i-1] : A[i];
                    return sum(A) - 2*a;
                }
            } else { // K <= 0
                return sum(A);
            }
        }
        return 0;
    }
    int sum(vector<int>& A) {
        int res{0};
        for (int a : A) res += a;
        return res;
    }
};

// 桶计数
class Solution {
public:
    int largestSumAfterKNegations(vector<int>& nums, int k) {
        unordered_map<int, int> freq;
        for (int& num : nums) {
            freq[num] += 1;
        }
        int res = accumulate(nums.begin(), nums.end(), 0);
        for (int i{-100}; i < 0; ++i) {
            if (freq[i] > 0) {
                int ops = min(k, freq[i]);
                res += ops * (-i) * 2; // 负的变成正的，总和加上两个 -i
                freq[i] -= ops;
                freq[-i] += ops;
                k -= ops;
                if (k == 0) {
                    break;
                }
            }
        }
        // k不是偶数，没有0
        if ((k > 0) && (k % 2 == 1) && (freq[0] == 0)) {
            for (int i{1}; i <= 100; ++i) {
                if (freq[i] > 0) {
                    res -= i * 2; // 正数变成负数
                    break;
                }
            }
        }
        return res;
    }
};
